# coding: utf8
import base64
import json
import sys
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex


class AesEncryption:
    def __init__(self, key):
        if isinstance(key, str):
            key = key.encode('utf-8')
        self.key = key
        self.mode = AES.MODE_CBC

        # 加密函数，如果text不是16的倍数【加密文本text必须为16的倍数！】，那就补足为16的倍数

    def encrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.key)
        text = text.encode("utf-8")
        # 这里密钥key 长度必须为16（AES-128）、24（AES-192）、或32（AES-256）Bytes 长度.目前AES-128足够用
        length = 16
        count = len(text)
        add = length - (count % length)
        text = text + (b'\0' * add)
        ciphertext = cryptor.encrypt(text)
        # 因为AES加密时候得到的字符串不一定是ascii字符集的，输出到终端或者保存时候可能存在问题
        # 所以这里统一把加密后的字符串转化为16进制字符串
        return ciphertext

        # 解密后，去掉补足的空格用strip() 去掉

    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.key)
        # plain_text = cryptor.decrypt(a2b_hex(text))
        plain_text = cryptor.decrypt(text)
        return plain_text.rstrip(b'\0').decode("utf-8")


class AESECB:
    def __init__(self, key):
        if not isinstance(key, bytes):
            key = base64.decodebytes(key.encode('utf-8'))
        self.cipher = AES.new(key)

    @staticmethod
    def pad(s):
        BS = AES.block_size
        return s + (BS - len(s) % BS) * bytes([BS - len(s) % BS])

    @staticmethod
    def unpad(s):
        return s[0:-(s[-1])]

    def encrypt(self, text):
        text = json.dumps(text).encode('utf-8')
        return base64.encodebytes(self.cipher.encrypt(self.pad(text)))

    def decrypt(self, text):
        decrypted = self.cipher.decrypt(base64.decodebytes(text))
        return self.unpad(decrypted).decode('utf-8')



# aes cbc pkcs5
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s: s[0:-ord(s[-1])]


class AESCipher:
        def __init__(self, key):
            if not isinstance(key, bytes):
                key = key.encode('utf-8')
            self.cipher = AES.new(key)

        @staticmethod
        def pad(s):
            BS = AES.block_size
            return s + (BS - len(s) % BS) * bytes([BS - len(s) % BS])

        @staticmethod
        def unpad(s):
            return s[0:-(s[-1])]

        def encrypt(self, text):
            # text = json.dumps(text).encode('')

            print(text)
            return base64.b64encode(self.cipher.encrypt(self.pad(text.encode("utf-8"))))

        def decrypt(self, text):
            decrypted = self.cipher.decrypt(base64.b64decode(text))
            return self.unpad(decrypted).decode('utf-8')
